import { fabric } from 'fabric';

export const Arrow = fabric.util.createClass(fabric.Rect, {
  type: 'arrow',

  initialize: function (options) {
    options || (options = {});
    options.noScaleCache = false;

    this.callSuper('initialize', options);
  },

  toObject: function () {
    return fabric.util.object.extend(this.callSuper('toObject'), {});
  },

  _render: function (ctx) {
    // 重点是保持箭头的等腰直角三角形组合

    // 箭尾的高度的一半（因为画图是从原点开始），整个箭尾高度是height * 0.4
    // 箭尾高度：整体高度 = 2:5
    const tailHeight = -this.height * 0.2;

    // 箭头实际高度/2 = 实际箭头宽度，因为箭头是两个等腰直角三角形拼成的
    // 因为下面的画图都是按照没有缩放时候算的，所以这里/ this.scaleX
    // 这里可以达到拉长宽度的时候，只有箭尾宽度发生变化，箭头仍旧是等腰直角三角形
    // 箭头展示高度 = 箭头绘图高度(h/arrowHeight) * scaleY = 箭头展示宽度 = 箭头绘图宽度(w/arrowWidth) * scaleX

    // 预期高度
    const h = this.height / 2;
    // 预期宽度
    const w = (h * this.scaleY) / this.scaleX;
    // 箭头的实际宽度，不能大于实际总宽度
    // 如果高度大过宽度太多，仍要保持上面所述的等腰直角三角形，所以 = width
    const arrowWidth = Math.min(this.width, w);
    // 实际高度同理从实际宽度推算
    // 同样需要乘除一下实际缩放系数，原因见上面注释
    const arrowHeight = (arrowWidth * this.scaleX) / this.scaleY;

    const y = -arrowHeight;
    const x = -this.width / 2;

    const arrowStartX = -x - arrowWidth;
    // halfHeight < actualHeight ? -x - arrowWidth : -x - arrowWidth - 16;

    ctx.beginPath();
    ctx.moveTo(x, -tailHeight);
    ctx.lineTo(arrowStartX, -tailHeight);
    ctx.lineTo(arrowStartX, -y);
    ctx.lineTo(-x, 0);
    ctx.lineTo(arrowStartX, y);
    ctx.lineTo(arrowStartX, tailHeight);
    ctx.lineTo(x, tailHeight);
    ctx.closePath();

    this._renderPaintInOrder(ctx);
  }
});

declare module 'fabric' {
  namespace fabric {
    class Arrow {
      static fromObject(object: fabric.Object, callback: Function): Arrow;
    }
  }
}
